﻿'Copyright (c) 2011 Kraigose Studios (Kraig C)

'Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"),
' to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense,
' and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions:

'The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software.

'THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
' FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
' LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
' IN THE SOFTWARE.

Imports System.IO
Imports System.Text
Imports System.Drawing

Module modTiles
    '' the pic stored as an array
    '' of Bytes?
    Public Structure Pic
        Public Pixels(,) As Byte
    End Structure

    '' Art File (*.ART)
    Public Structure ArtFile
        Public Filename As String
        Public Version As Integer
        Public NumTiles As Integer
        Public LocalStart As Integer
        Public LocalEnd As Integer
        Public XSizes() As Integer
        Public YSizes() As Integer
        Public Properties() As Integer
        Public PicData() As Pic
        Public ArtNum As Byte
    End Structure

    Public currTileNumInFile As Integer = 0

    Public currFileNum As Integer
    Public currTileNumOverall As Integer

    '' Opens an ART file
    Public Sub OpenArt(ByRef fs As FileStream, ByRef currArtFile As ArtFile)
        Dim i As Integer
        Dim o As Integer
        Dim p As Integer

        Dim binr As BinaryReader = New BinaryReader(fs) ' Binary File

        Try
            Dim buff(4) As Byte ' Buffer

            If (binr IsNot Nothing) Then
                With currArtFile
                    .ArtNum = Val(Right(Left(Right(fs.Name, Len(fs.Name) - i), 8), 3))
                    o = -1

                    Do Until o = -1
                        If o = -1 Then o = 0
                        i = o
                        o = InStr(o + 1, fs.Name, "\")
                    Loop

                    ' Art Header processing
                    buff = binr.ReadBytes(4)
                    .Version = BitConverter.ToInt32(buff, 0)
                    Array.Clear(buff, 0, 4)
                    buff = binr.ReadBytes(4)
                    Array.Clear(buff, 0, 4)
                    .LocalStart = BitConverter.ToInt32(binr.ReadBytes(4), 0)
                    .LocalEnd = BitConverter.ToInt32(binr.ReadBytes(4), 0)
                    .NumTiles = .LocalEnd - .LocalStart + 1

                    ReDim .XSizes(.NumTiles)
                    ReDim .YSizes(.NumTiles)
                    ReDim .Properties(.NumTiles)
                    ReDim .PicData(.NumTiles)

                    For i = 1 To .NumTiles
                        buff = binr.ReadBytes(2)
                        .XSizes(i) = BitConverter.ToInt16(buff, 0)
                        Array.Clear(buff, 0, 2)
                    Next i

                    For i = 1 To .NumTiles
                        buff = binr.ReadBytes(2)
                        .YSizes(i) = BitConverter.ToInt16(buff, 0)
                        Array.Clear(buff, 0, 2)
                    Next i

                    For i = 1 To .NumTiles
                        buff = binr.ReadBytes(4)
                        .Properties(i) = BitConverter.ToInt32(buff, 0)
                        Array.Clear(buff, 0, 4)
                    Next i

                    For i = 1 To .NumTiles
                        ReDim .PicData(i).Pixels(.XSizes(i), .YSizes(i))
                        For o = 1 To .XSizes(i)
                            For p = 1 To .YSizes(i)
                                .PicData(i).Pixels(o, p) = binr.ReadByte()
                            Next p
                        Next o
                    Next i
                End With
            End If
        Catch ex As Exception
            Console.WriteLine(ex.ToString() & vbNewLine)
        End Try
        binr.Close()
        fs.Close()

    End Sub

    Public Sub SaveArtFile(ByVal fnamepath As String, ByRef cartf As ArtFile)
        Dim fs As FileStream
        Try
            fs = New FileStream(fnamepath, FileMode.Create, FileAccess.Write)
            Dim bwrite As New BinaryWriter(fs)

            Dim i As Integer
            Dim o As Integer
            Dim p As Integer

            Dim HeaderEnd As Long
            Dim XSizeEnd As Long
            Dim YSizeEnd As Long
            Dim PropsEnd As Long

            With cartf
                HeaderEnd = Len(.Version) + 4 + Len(.LocalStart) + Len(.LocalEnd) + 1
                XSizeEnd = HeaderEnd + 2 * .NumTiles
                YSizeEnd = HeaderEnd + 2 * .NumTiles
                PropsEnd = YSizeEnd + 4 * .NumTiles

                ' Write The Header
                bwrite.Write(.Version)
                bwrite.Write(.NumTiles)
                bwrite.Write(.LocalStart)
                bwrite.Write(.LocalEnd)

                For i = 1 To .NumTiles
                    bwrite.Write(.XSizes(i))
                Next i

                For i = 1 To .NumTiles
                    bwrite.Write(.YSizes(i))
                Next i

                For i = 1 To .NumTiles
                    bwrite.Write(.Properties(i))
                Next i

                For i = 1 To .NumTiles
                    ReDim .PicData(i).Pixels(.XSizes(i), .YSizes(i))
                    For o = 1 To .XSizes(i)
                        For p = 1 To .YSizes(i)
                            bwrite.Write(.PicData(i).Pixels(o, p))
                        Next p
                    Next o
                Next i
            End With



        Catch ex As Exception
            Console.WriteLine(ex.ToString() & vbNewLine)
        End Try

    End Sub

    Public Function GetProps(ByVal afile As ArtFile, ByVal currindex As Integer) As PropertiesInfo
        Dim bytes() As Byte = BitConverter.GetBytes(afile.Properties(currindex))
        Dim barray As New BitArray(bytes)
        Dim anbarray As New BitArray(6)
        Dim atbarray As New BitArray(2)
        Dim ofxarray As New BitArray(8)
        Dim ofyarray As New BitArray(8)
        Dim sparray As New BitArray(4)
        Dim narray As New BitArray(4)

        Dim retProps As PropertiesInfo

        Dim counter As Integer = 0
        Dim counter2 As Integer = 0
        Dim o As [Object]
        For Each o In barray
            If counter >= 0 And counter <= 5 Then
                anbarray.Set(counter, barray(counter))
            ElseIf counter >= 6 And counter <= 7 Then
                atbarray.Set(counter - 6, barray(counter))
            ElseIf counter >= 8 And counter <= 15 Then
                ofxarray.Set(counter - 8, barray(counter))
            ElseIf counter >= 16 And counter <= 23 Then
                ofyarray.Set(counter - 16, barray(counter))
            ElseIf counter >= 24 And counter <= 27 Then
                sparray.Set(counter - 24, barray(counter))
            ElseIf counter >= 28 Then
                narray.SetAll(False)
            End If
            counter += 1
        Next o

        Try
            retProps.animtype = Integer.Parse(ConvertBArrayToByte(atbarray))
            retProps.animframes = Integer.Parse(ConvertBArrayToByte(anbarray))
            retProps.offsetX = Integer.Parse(ConvertBArrayToByte(ofxarray))
            retProps.offsetY = Integer.Parse(ConvertBArrayToByte(ofyarray))
            retProps.speed = Integer.Parse(ConvertBArrayToByte(sparray))
        Catch

        End Try
        Dim retp As Point = SetOffsetsProper(retProps.offsetX, retProps.offsetY)
        retProps.offsetX = retp.X
        retProps.offsetY = retp.Y
        Return retProps
    End Function

    Public Sub SetProps(ByRef afile As ArtFile)
        Dim bytes(4) As Byte
        Dim barray As New BitArray(bytes)
        Dim anbarray As New BitArray(6)
        Dim atbarray As New BitArray(2)
        Dim ofxarray As New BitArray(8)
        Dim ofyarray As New BitArray(8)
        Dim sparray As New BitArray(4)
        Dim narray As New BitArray(4) ' Buffer (Unused)

        'Dim animtype As Integer = frmProp.cmbAnimtype.SelectedIndex
        'Dim animframes As Integer = frmProp.nudFrames.Value
        'Dim offsetX As Integer = frmProp.nudOffX.Value
        'Dim offsetY As Integer = frmProp.nudOffY.Value
        'Dim speed As Integer = frmProp.nudSpeed.Value

        Dim counter As Integer = 0
        Dim counter2 As Integer = 0
        Dim o As [Object]
        For Each o In barray
            If counter >= 0 And counter <= 5 Then
                barray.Set(counter, anbarray(counter))
            ElseIf counter >= 6 And counter <= 7 Then
                barray.Set(counter, atbarray(counter - 6))
            ElseIf counter >= 8 And counter <= 15 Then
                barray.Set(counter, ofxarray(counter - 8))
            ElseIf counter >= 16 And counter <= 23 Then
                barray.Set(counter, ofyarray(counter - 16))
            ElseIf counter >= 24 And counter <= 27 Then
                barray.Set(counter, sparray(counter - 24))
            ElseIf counter >= 28 Then
                barray.Set(counter, sparray(counter - 32))
            End If
            counter += 1
        Next o

        Dim iar(1) As Integer
        barray.CopyTo(iar, 0)

        Dim prop As Integer = iar(0)

        afile.Properties(currTileNumInFile) = prop

    End Sub

    Private Function ConvertBArrayToByte(ByVal bar As BitArray) As Byte

        If (bar.Count > 8) Then
            Return 0
        End If

        Dim result As Byte = 0

        For i = bar.Count - 1 To 0 Step -1
            If (bar.Get(i)) Then
                result = result Or (1 << i)
            End If
        Next i

        Return result
    End Function

    Private Function SetOffsetsProper(ByVal ox As Byte, ByVal oy As Integer) As Point
        Dim retp As Point
        retp.X = ConvertNumToOffsetProper(ox)
        retp.Y = ConvertNumToOffsetProper(oy)
        Return retp
    End Function

    Private Function ConvertNumToOffsetProper(ByVal off As Integer) As Integer
        Dim ret As Integer
        If off < 127 And off >= 1 Then
            ret = -(off)
        ElseIf off <= 255 And off >= 128 Then
            ret = 256 - off
        Else
            ret = 0
        End If
        Return ret
    End Function

End Module
